package com.dongyun.loraweb.util;

import org.slf4j.helpers.MessageFormatter;

import java.awt.*;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class StrUtil {


	private static String ip;

	public static final String DATE_PATTERN = "yyyy-MM-dd";
	public static final String TIME_PATTERN = "HH:mm:ss";
	public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
	public static final String SERIAL_PATTERN = "yyyyMMddHHmmss";
    public static final int SMAIL_KEY_ENTER = 16777296;
    public static final int BIG_KEY_ENTER = 13;
    public static final int BACKSPACE = 8;
    public static final int DELETE = 127;

	public static String formatDate(Date date, String pattern) {
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		if(date == null){
			return "";
		}
		return sdf.format(date);
	}

	public static Date parseDate(String dateStr){
		return parse(dateStr, DATE_PATTERN);
	}

	public static Date parseDateTime(String dateStr){
		return parse(dateStr,DATETIME_PATTERN);
	}

	public static Date parse(String dateStr,String pattern){
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		try {
			return sdf.parse(dateStr);
		} catch (Exception e) {
			return null;
		}
	}

	public static String formatDateTime(Date date) {
		return formatDate(date, DATETIME_PATTERN);
	}

	public static String formatDate(Date date) {
		return formatDate(date, DATE_PATTERN);
	}

    public static String formatTime(Date date) {
        return formatDate(date, TIME_PATTERN);
    }

	public static boolean isEmpty(String s) {
		return s == null || s.trim().length() == 0;
	}

	public static boolean isEmpty(byte[] obj) {
		return obj == null || obj.length == 0;
	}

	public static boolean isEmpty(Map m) {
		return m == null || m.isEmpty();
	}

    public static boolean isEmpty(Object o) {
        return o == null;
    }

    public static boolean isEmpty(Object[] obj) {
		return obj == null || obj.length == 0;
	}

    public static boolean isEmpty(Collection s) {
        return s == null || s.isEmpty();
    }

    public static boolean isNotEmpty(Collection s) {
        return !isEmpty(s);
    }

    public static boolean isNotEmpty(Object[] obj) {
        return !isEmpty(obj);
    }
	/**
     * 计算本月的工作日数量
     * @param year
     * @param month
     * @return
     */
    public static int getworkDaySize(int year,int month){
    	int result = 0;
    	Calendar instance = Calendar.getInstance();
    	instance.set(year, month-1, 1);
    	int maxDate = instance.getActualMaximum(Calendar.DATE);
    	for (int i = 1; i <= maxDate; i++) {
    		instance.set(year, month-1, i);
    		int DAY_OF_WEEK = instance.get(Calendar.DAY_OF_WEEK);
    		if(DAY_OF_WEEK != Calendar.SUNDAY && DAY_OF_WEEK != Calendar.SATURDAY){
    			result ++;
    		}
		}
    	return result;
    }

    public static boolean isSameDay(Date date1,Date date2){
    	String formatDate = formatDate(date1);
    	String formatDate2 = formatDate(date2);
    	return formatDate.equals(formatDate2);
    }
    /**
     * 获取指定日期的当天最早时间
     * @param d
     * @return
     */
	public static Date getTodayTopTime(Date d){
		if(d == null) return null;
		return getFixTime(d, 0, 0, 0);
	}

    /**
     * 获取指定日期的当天最晚时间
     * @param d
     * @return
     */
	public static Date getTodayBottomTime(Date d){
		if(d == null) return null;
		return getFixTime(d,23,59,59);
	}

    /**
     * 获取本周最早的一个时间点
     *
     * @param d
     * @return
     */
    public static Date getWeekTopTime(Date d) {
        if (d == null) return null;
        return getFixTime(d, 1, 0, 0, 0);
    }

    /**
     * 获取本周最晚的一个时间点
     *
     * @param d
     * @return
     */
    public static Date getWeekBottomTime(Date d) {
        if (d == null) return null;
        return getFixTime(d, 7, 23, 59, 59);
    }

    /**
     * 获取当月最早的一个时间点
     *
     * @param d
     * @return
     */
    public static Date getMonthTopTime(Date d) {
        if (d == null) return null;
        Calendar instance = Calendar.getInstance();
        instance.setTime(d);
        instance.set(Calendar.DAY_OF_MONTH, 1);
        instance.set(Calendar.HOUR_OF_DAY, 0);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.SECOND, 0);
        return instance.getTime();
    }

    /**
     * 获取当月最晚的一个时间点
     *
     * @param d
     * @return
     */
    public static Date getMonthBottomTime(Date d) {
        if (d == null) return null;
        Calendar instance = Calendar.getInstance();
        instance.setTime(d);
        instance.set(Calendar.DAY_OF_MONTH, 1);
        instance.set(Calendar.HOUR_OF_DAY, 23);
        instance.set(Calendar.MINUTE, 59);
        instance.set(Calendar.SECOND, 59);
        
        instance.add(Calendar.MONTH, 1);
        instance.add(Calendar.DAY_OF_WEEK, -1);
        return instance.getTime();
    }
    
    /**
     * 获得季度最晚一个时间点
     * @param d
     * @return
     */
    public static Date getQuarterBottonTime(Date d){
    	if (d == null) return null;
    	 Calendar instance=Calendar.getInstance();
    	 instance.setTime(d);
         int month=instance.get(instance.MONTH)+1;
         
         if(month>=1&&month<=3){     
        	 instance.set(Calendar.DAY_OF_MONTH, 3);
         }     
         if(month>=4&&month<=6){    
        	 instance.set(Calendar.DAY_OF_MONTH, 6);
         }     
         if(month>=7&&month<=9){     
        	 instance.set(Calendar.DAY_OF_MONTH, 9);
         }     
         if(month>=10&&month<=12){ 
        	 instance.set(Calendar.DAY_OF_MONTH, 12);
         }
         instance.set(Calendar.HOUR_OF_DAY, 23);
         instance.set(Calendar.MINUTE, 59);
         instance.set(Calendar.SECOND, 59);
         
         instance.add(Calendar.MONTH, 1);
         instance.add(Calendar.DAY_OF_WEEK, -1);
         return instance.getTime();
        
    }
    
    /**
     * 获取当年最早的一个时间点
     *
     * @param d
     * @return
     */
    public static Date getYearTopTime(Date d) {
        if (d == null) return null;
        Calendar instance = Calendar.getInstance();
        instance.setTime(d);
        instance.set(Calendar.DAY_OF_YEAR, 1);
        instance.set(Calendar.HOUR_OF_DAY, 0);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.SECOND, 0);
        return instance.getTime();
    }

    /**
     * 获取当年的最后一个时间点
     *
     * @param d
     * @return
     */
    public static Date getYearBottomTime(Date d) {
        if (d == null) return null;
        Calendar instance = Calendar.getInstance();
        instance.setTime(d);
        instance.set(Calendar.DAY_OF_YEAR, 1);
        instance.set(Calendar.HOUR_OF_DAY, 23);
        instance.set(Calendar.MINUTE, 59);
        instance.set(Calendar.SECOND, 59);

        instance.add(Calendar.YEAR, 1);
        instance.add(Calendar.DAY_OF_YEAR, -1);
        return instance.getTime();
    }

    /**
     * 修正时间
     *
     * @param date
     * @param h
     * @param m
     * @param s
     * @return
     */
    public static Date getFixTime(Date date, int h, int m, int s) {
    	if(date == null) return null;
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        instance.set(Calendar.HOUR_OF_DAY, h);
        instance.set(Calendar.MINUTE, m);
        instance.set(Calendar.SECOND, s);
        return instance.getTime();
    }

    /**
     * 修正周
     *
     * @param date
     * @param week
     * @param h
     * @param m
     * @param s
     * @return
     */
    public static Date getFixTime(Date date, int week, int h, int m, int s) {
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        instance.set(Calendar.DAY_OF_WEEK, week);
        instance.set(Calendar.HOUR_OF_DAY, h);
        instance.set(Calendar.MINUTE, m);
        instance.set(Calendar.SECOND, s);
        return instance.getTime();
    }

    /**
     * 修正日期
     *
     * @param date
     * @param day
     * @param h
     * @param m
     * @param s
     * @return
     */
    private static Date getFixMonthTime(Date date, int day, int h, int m, int s) {
        Calendar instance = Calendar.getInstance();
        instance.setTime(date);
        instance.set(Calendar.DAY_OF_MONTH, day);
        instance.set(Calendar.HOUR_OF_DAY, h);
        instance.set(Calendar.MINUTE, m);
        instance.set(Calendar.SECOND, s);
        return instance.getTime();
    }

    public static Date fixDate(Date startTime, Date date) {
        String startTimeStr = formatDateTime(startTime);
        String dateStr = formatDateTime(date);
        String resultStr = dateStr.substring(0,11)+startTimeStr.substring(11);
        return parseDateTime(resultStr);
    }
    /**
     * 比较日期的大小
     * @param d
     * @param d2
     * @return
     */
	public static int TimeCompareTo(Date d,Date d2){
		String dStr = formatDate(d, "HH:mm:ss");
		String d2Str = formatDate(d2,"HH:mm:ss");
		return dStr.compareTo(d2Str);
	}

    /**
     * 日期相减的小时分钟差
     * @param timestamp
     * @param date
     * @return
     */
	public static String MinusTime2(Date timestamp, Date date) {
        if (timestamp == null || date == null) {
            return "0:0:0";
        }
        long minus = Math.abs(date.getTime() - timestamp.getTime());
		long hour = minus/1000/60/60;
		long min = (minus - hour*60*60*1000)/1000/60;
		long sec =(minus - hour*60*60*1000 - min*1000*60)/1000;
		String h =String.format("%2d", hour);
		String m=String.format("%2d", min);
		String s=String.format("%2d", sec);
		return h + ":" + m + ":" + s;
	}

    public static long betweenDays(Date timestamp, Date date) {
        long minus = Math.abs(date.getTime() - timestamp.getTime());
        long hour = minus/1000/60/60;
        if(hour % 24 != 0){
            return hour / 24 + 1;
        }
        else{
            return hour/24;
        }
    }

    public static boolean isBetweenTime(Date date,Date start,Date end){
        String dateStr = formatDate(date,TIME_PATTERN);
        String startStr = formatDate(start, TIME_PATTERN);
        String endStr = formatDate(end,TIME_PATTERN);
        
        //例如 00:00:00 < 13:21:13 < 15:00:00
        if(startStr.compareTo(dateStr) <= -1 && endStr.compareTo(dateStr) >= 1){
            return true;
        }

        return false;
    }

    /**
     * 获取当前月份所在的季度,0表示第一季节
     * @return
     */
    public static int getCurrentSeason(){
        int i = Calendar.getInstance().get(Calendar.MONTH)+1;
        if(i >= 1 && i <= 3 ){
            return 0;
        }else if(i >= 4 && i <= 6 ){
            return 1;
        }else if(i >= 7 && i <= 9 ){
            return 2;
        }else{
            return 3;
        }
    }


    public static String checkPath(String fileSavePath, String[] strings, String s) {
        if(isEmpty(fileSavePath)){
            return null;
        }
        for(String path : strings){
            if(fileSavePath.endsWith(path)){
                return fileSavePath;
            }
        }
        
        return fileSavePath+s;
    }

	public static boolean checkFileType(String selectToOpen, String[] strings) {
		boolean result = false;
		for (String string : strings) {
			if(selectToOpen.endsWith(string)){
				result = true;
			}
		}
		return result;
	}
	
	/**
	 * 数字金额大写转换，思想先写个完整的然后将如零拾替换成零
	 * 要用到正则表达式
	 */	
	public static String toRMB(double money) {  
	    char[] s1 = {'零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'};  
	    char[] s4 = {'分', '角', '元', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿', '拾', '佰', '仟', '万'};  
	        String str = String.valueOf(Math.round(money * 100 + 0.00001));  
	        String result = "";  
	   
	    for (int i = 0; i <str.length(); i++) {  
	    int n = str.charAt(str.length() - 1 - i) - '0';  
	    result = s1[n] + "" + s4[i] + result;  
	        }  
	   
	        result = result.replaceAll("零仟", "零");  
	        result = result.replaceAll("零佰", "零");  
	        result = result.replaceAll("零拾", "零");  
	        result = result.replaceAll("零亿", "亿");  
	        result = result.replaceAll("零万", "万");  
	        result = result.replaceAll("零元", "元");  
	        result = result.replaceAll("零角", "零");  
	        result = result.replaceAll("零分", "零");  
	   
	        result = result.replaceAll("零零", "零");  
	        result = result.replaceAll("零亿", "亿");  
	        result = result.replaceAll("零零", "零");  
	        result = result.replaceAll("零万", "万");  
	        result = result.replaceAll("零零", "零");  
	        result = result.replaceAll("零元", "元");  
	        result = result.replaceAll("亿万","亿");  
	 
	        result = result.replaceAll("零$", "");  
	        result = result.replaceAll("元$", "元");  
	        result = result.replaceAll("角$", "角");  
	   
	    return result;  
	}
	

		public static InetAddress getInetAddress(){

		    try{
		    	return InetAddress.getLocalHost();
		    }catch(UnknownHostException e){
				System.out.println("unknown host!");
			}
		    return null;

		}

		public static String getHostIp(){
            String getenv = System.getenv("ip");
            if (StrUtil.isNotNullOrEmpty(getenv)){
                return getenv;
            }
            if(!isEmpty(ip)){
				return ip;
			}
			InetAddress netAddress = getInetAddress();
			if(null == netAddress){
				return null;
			}
			String ip = netAddress.getHostAddress();
			return ip;
		}

		public static String getHostName(){
			InetAddress netAddress = getInetAddress();
			if(null == netAddress){
				return null;
			}
            String name = netAddress.getHostName();
            return name;
        }

    
    /**
     * 日期相减的小时分钟差
     * @param time1
     * @param time2
     * @return
     */
    public static int MinusMinute(Date time1, Date time2) {
        Calendar instance1 = Calendar.getInstance();
        instance1.setTime(time1);
        int hour1 = instance1.get(Calendar.HOUR_OF_DAY);
        int min1 = instance1.get(Calendar.MINUTE);

        Calendar instance2 = Calendar.getInstance();
        instance2.setTime(time2);
        int hour2 = instance2.get(Calendar.HOUR_OF_DAY);
        int min2 = instance2.get(Calendar.MINUTE);

        return Math.abs((hour1 * 60 + min1) - (hour2*60 + min2));
    }

    public static Boolean checkDateIsBetween(Date startTime, Date endTime, Date startTime1, Date endTime1) {
        String startTimeStr = formatTime(startTime);
        String endTimeStr = formatTime(endTime);
        String startTimeStr2 = formatTime(startTime1);
        String endTimeStr2 = formatTime(endTime1);

        //startTime1 在 startTime与endTime之间
        if(startTimeStr2.compareTo(startTimeStr) > 0 && startTimeStr2.compareTo(endTimeStr) < 0){
            return true;
        }
        //endTime1 在 startTime与endTime之间
        if(endTimeStr2.compareTo(startTimeStr) > 0 && endTimeStr2.compareTo(endTimeStr) < 0){
            return true;
        }
        //startTime1与endTime1 将startTime与endTime包围
        if(startTimeStr.compareTo(startTimeStr2) > 0 && endTimeStr.compareTo(endTimeStr2) < 0){
            return true;
        }
        //时间点相等
        if(startTimeStr.compareTo(startTimeStr2) == 0 || startTimeStr.compareTo(endTimeStr2) == 0){
            return true;
        }
        //时间点相等
        if(endTimeStr.compareTo(startTimeStr2) == 0 || endTimeStr.compareTo(endTimeStr2) == 0){
            return true;
        }
        return false;
    }
    
    /**
     * 获取该月多少天
     * @param year
     * @param month
     * @return
     */
    public static int getDayOfMonth(int year,int month){
    	Calendar c=Calendar.getInstance(Locale.CHINA);
    	c.set(year, month-1, 1);
    	return c.getActualMaximum(Calendar.DATE);
    }
    
    
    public static String StringXor(String Str, String key)
	{
	    int vKeyLen = key.length();
	    char[] StrChars = Str.toCharArray();
	    char[] KeyChars = key.toCharArray();
	    for (int i = 0; i < Str.length(); i++){
	    	for(int j = 0; j < key.length(); j++){
	    		StrChars[i] ^= KeyChars[j++ % key.length()];
	    		StrChars[i] ^=(j+i)^j^i;
	    	}
	    }
	    return new String(StrChars);
	}

	public static int parseInt(String str) {
		try {
			int parseInt = Integer.parseInt(str);
			return parseInt;
		} catch (NumberFormatException e) {
			return 0;
		}
		
	}
	/**
	 * 判断是否为测试版
	 * @return
	 */
	public static boolean isVersionTypeBeta() {
		String property = System.getProperty("versionType");
		boolean equals = property.equals("test");
		return equals;
	}

	public static boolean checkTimeIsBefore(Date one, Date two) {
		Calendar c1=Calendar.getInstance();
		Calendar c2=Calendar.getInstance();
		c1.setTime(one);
		c1.set(2000, 1, 1);
		c2.setTime(two);
		c2.set(2000, 1, 1);
		long qq=c1.getTimeInMillis()-c2.getTimeInMillis();
		if(qq>-1000){
			return false;
		}
		return true;
	}

    public static boolean checkUrl(String dbRemoteUrl,int timeout) {
        try {
            URL url = new URL(dbRemoteUrl);
            URLConnection openConnection = url.openConnection();
            openConnection.setConnectTimeout(timeout);
            openConnection.connect();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

	public static  List<Date> getWeekendOfYear(int i) {
		Calendar calendar =Calendar.getInstance(); //当前日期
		calendar.set(Calendar.YEAR,i);
        Calendar cstart =Calendar.getInstance(); 
        Calendar cend =Calendar.getInstance(); 
        cstart.set(i, 0, 1);//2010-1-1
        cend.set(i+1, 0, 1);//2011-1-1
        List<Date> list=new ArrayList<Date>();
        calendar.add(Calendar.DAY_OF_MONTH,-calendar.get(Calendar.DAY_OF_WEEK)); //周六
        Calendar d = (Calendar)calendar.clone();
        //向前
        for(;calendar.before(cend)&&calendar.after(cstart);calendar.add(Calendar.DAY_OF_YEAR, -7))
        {
        	Calendar cc = (Calendar) calendar.clone();
        	cc.add(Calendar.DAY_OF_YEAR, 1);
        	list.add(calendar.getTime());
        	if (cc.get(Calendar.YEAR)==i)
        	list.add(cc.getTime());
        }
        //向后
        d.add(Calendar.DAY_OF_YEAR, 7);
        for(;d.before(cend)&&d.after(cstart);d.add(Calendar.DAY_OF_YEAR, 7))
        {
        	Calendar cc = (Calendar) d.clone();
        	cc.add(Calendar.DAY_OF_YEAR, 1);
        	list.add(d.getTime());
        	if (cc.get(Calendar.YEAR)==i) {
        		list.add(cc.getTime());
			}
        }
		return list;
	}

	public static void keyPress(int... key) {
			try {
				Robot r=new Robot();
				for (int i : key) {
					 r.keyPress(i);
				  r.keyRelease(i);
				}
				r.delay(100);
				 
			} catch (AWTException e) {
				e.printStackTrace();
			}
		
	}

    public static boolean isNotNullOrEmpty(String str) {
        return str != null && !str.isEmpty();
    }

    public static String joinCharArray(char[] chars) {
        StringBuilder sb = new StringBuilder(chars.length);
        for (char c : chars) {
            sb.append(c);
        }
        return sb.toString();
    }

    public static String reverse(String str){
        char[] charArray = str.toCharArray();
        int length = charArray.length;
        for (int i = 0; i < length/2; i++) {
            char c = charArray[i];
            charArray[i] = charArray[length -i-1];
            charArray[length -i-1] = c;
        }
        return joinCharArray(charArray);
    }

    public static boolean isProfileForProject(String wuHanXueYuan) {
        return !StrUtil.isEmpty(System.getenv(wuHanXueYuan));
    }


    public static String formatDateTime(Date date, String dateFormat, Locale us, String timeZone) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat, us);
        if (timeZone != null){
            simpleDateFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
        }
        return simpleDateFormat.format(date);
    }

	public static String formatString(String content, Object... o) {
		return MessageFormatter.arrayFormat(content, o).getMessage();
	}

    public static String isEmptyToString(String s, String s1) {
        return isEmpty(s) ? s1 : s;
    }

    public static Date parseIDCardToBirthDay(String IDCard){
        if (IDCard == null) {
            return null;
        }
        if (IDCard.length() != 15 && IDCard.length() != 18){
            return null;
        }
        String substring = IDCard.substring(6, 14);
        return parse(substring,"yyyyMMdd");
    }

    public static boolean isIDCard(String IDCard) {
        if (IDCard == null) {
            return false;
        }
        return IDCard.length() == 15 || IDCard.length() == 18;
    }

    public static String MinusTime2(String topTime, String bottomTime) {
        return MinusTime2(parse(topTime,TIME_PATTERN),parse(bottomTime,TIME_PATTERN));
    }


    public static String isNullToEmpty(Enum nationality) {
        return nationality == null ? "" : nationality.toString();
    }


    /**
	 * 计算两个时间的时间差
	 * @param startTime
	 * @param endTime
	 * @param timeUnit
	 * @return
	 */
	public static int countTime(Date startTime, Date endTime, TimeUnit... timeUnit) {
		Long millis=endTime.getTime()-startTime.getTime();
		Long second;
		Long minute;
		Long hour;
		Long day;
		if (timeUnit==null||timeUnit[0].equals(TimeUnit.MILLISECONDS)) {
			return millis.intValue();
		}
		if (timeUnit[0].equals(TimeUnit.SECONDS)) {
			second=millis/1000;
			return second.intValue();
		}
		if (timeUnit[0].equals(TimeUnit.MINUTES)) {
			minute=millis/1000/60;
			return minute.intValue();
		}
		if (timeUnit[0].equals(TimeUnit.HOURS)) {
			hour=millis/1000/60/60;
			return hour.intValue();
		}
		if (timeUnit[0].equals(TimeUnit.DAYS)) {
			day=millis/1000/60/60/24;
			return day.intValue();
		}
		return 0;
	}

	public static boolean isEmpty(String value, String... emptys) {
		boolean isEmpty=value==null||value.trim().isEmpty();
		if (!isEmpty(emptys)) {
			isEmpty=isEmpty||Arrays.asList(emptys).contains(value.trim());
		}
		return isEmpty;
	}
}